package top.chenyaohua.asm;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;

import java.util.*;

public class CustomAnnotationVisitor extends AnnotationVisitor {

    private AnnotationMetadata annotationMetadata;

    private  CustomClassVisit customClassVisit;

    private  CustomFieldVisitor customFieldVisitor;

    private  CustomMethodVisit custommethodvisit;

    public CustomAnnotationVisitor (AnnotationVisitor av, CustomClassVisit customClassVisit,
                                    CustomFieldVisitor customFieldVisitor,CustomMethodVisit custommethodvisit) {
        super(Opcodes.ASM5, av);

        //根据线程调用栈获取上一个调用方法所在的类
        final String className = Thread.currentThread().getStackTrace()[2].getClassName();

        switch (className){
            case "top.chenyaohua.asm.CustomClassVisit":
                List<AnnotationMetadata> annotations = customClassVisit.getBeanMetadata().getAnnotations();
                this.annotationMetadata = annotations.get(annotations.size() - 1);
                break;
            case "top.chenyaohua.asm.CustomFieldVisitor":
                List<AnnotationMetadata> customFieldAnnotations = customFieldVisitor.getFieldMetadata().getAnnotations();
                this.annotationMetadata = customFieldAnnotations.get(customFieldAnnotations.size() - 1);
                break;
            case "top.chenyaohua.asm.CustomMethodVisit":
                List<AnnotationMetadata> customMethodAnnotations = custommethodvisit.getMethodMetadata().getAnnotations();
                this.annotationMetadata = customMethodAnnotations.get(customMethodAnnotations.size() - 1);
        }

        this.customFieldVisitor = customFieldVisitor;
        this.custommethodvisit = custommethodvisit;
        this.customClassVisit = customClassVisit;


    }


    @Override
    public void visit (String name, Object value) {

        if(name == null){
            MethodMetadata methodMetadata = custommethodvisit.getMethodMetadata();
            methodMetadata.setAnnotationDefault(value);
        }else {
            Map<String, Object> params = Optional.ofNullable(annotationMetadata.getParams()).orElseGet(HashMap::new);
            params.put(name, value);
            annotationMetadata.setParams(params);
        }
        super.visit(name, value);
    }

    public AnnotationMetadata getAnnotationMetadata () {
        return annotationMetadata;
    }

    public CustomClassVisit getCustomClassVisit () {
        return customClassVisit;
    }

    public CustomFieldVisitor getCustomFieldVisitor () {
        return customFieldVisitor;
    }

    public CustomMethodVisit getCustommethodvisit () {
        return custommethodvisit;
    }


}
